/*
 * schedualer.c
 *
 *  Created on: Oct 21, 2009
 *      Author: nreimens
 */
#include "glob.h"
#include "schedualer.h"
#include <time.h>
int switches = 1;
int timeticks = 0;
struct timeval tm;
time_t one=0, total=0;
int init_schedual(SCHEDUALER * sdlr, VMEMMOD* vm) {
	one = time(NULL);
	if (vm && sdlr) {
		sdlr->mm = vm->mm;
		queueInit(&(sdlr->rdyQ));
		enqueue(sdlr->rdyQ, 1);
		sdlr->timeTick = TIMETICKS;
		(sdlr->mm)->nCurrProc = dequeue(sdlr->rdyQ);
	} else {
		printf("please intialize the schedualer/memorymodual \n");
		return -1;
	}
	return 0;
}

int schedual(SCHEDUALER * sdlr, int flag, int* pid, int pageFaults) {
	if (sdlr->mm) {

		/* Add the new process to the ready queue */
		if((*pid) != (-1)){
			enqueue(sdlr->rdyQ, (*pid));
			(*pid) = (-1);
		}
		if (flag == 0) {
			(sdlr->timeTick)--;
			if (sdlr->timeTick == 0) {
				switches++; gettimeofday(&tm,NULL); total += tm.tv_usec - one; one = tm.tv_usec;
				enqueue(sdlr->rdyQ, sdlr->mm->nCurrProc);
				sdlr->mm->nCurrProc = dequeue(sdlr->rdyQ);
				sdlr->timeTick = TIMETICKS;
			}
		} else if (flag == 1) {
			(sdlr->mm->nNumProgs)--;
			if (sdlr->mm->nNumProgs > 1) {
				switches++; timeticks += sdlr->timeTick; gettimeofday(&tm,NULL); total += tm.tv_usec - one; one = tm.tv_usec;
				(sdlr->mm)->nCurrProc = dequeue(sdlr->rdyQ);
				sdlr->timeTick = TIMETICKS;
			}else {
				printf("Timeslice: %d  Context switches: %d  with and average of %d  timeticks remaining\n",
						TIMETICKS, switches, timeticks / switches);
				printf("total number of page faults: %d\n",pageFaults);
				total = time(NULL);
				printf("Time spent: %d\n",total-one);

				printf("End of BRAIN\n");
				//clean_mem(&(sdlr->mm));
				exit(EXIT_SUCCESS); //call clean routine
			}
		} else if (flag == 2) {
			switches++; timeticks += sdlr->timeTick;  gettimeofday(&tm,NULL); total += tm.tv_usec - one; one = tm.tv_usec;
			enqueue(sdlr->rdyQ, sdlr->mm->nCurrProc); //receive failed, so put process on the end of the queue.
			sdlr->mm->nCurrProc = dequeue(sdlr->rdyQ);
			sdlr->timeTick = TIMETICKS;
		} else if (flag == 3) {
			switches++; timeticks += sdlr->timeTick;
			sdlr->mm->nCurrProc = dequeue(sdlr->rdyQ); //we have a send message, so block and don't requeue it
			sdlr->timeTick = TIMETICKS;
		} else if (flag == 4) { //successful receive, so we put the process back on the ready queue.
			enqueue(sdlr->rdyQ, disasm(sdlr->mm->pcb[sdlr->mm->nCurrProc - 1].reg));
			(sdlr->timeTick)--;
			if (sdlr->timeTick == 0) {
				switches++; gettimeofday(&tm,NULL); total += tm.tv_usec - one; one = tm.tv_usec;
				enqueue(sdlr->rdyQ, sdlr->mm->nCurrProc);
				sdlr->mm->nCurrProc = dequeue(sdlr->rdyQ);
				sdlr->timeTick = TIMETICKS;
			}

		}

	} else {
		printf("please initialize the scheduler\n");
		return -1;
	}
	return 0;
}

